﻿using FreeSql.Internal.CommonProvider;
using FreeSql.Internal;
using FreeSql;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using System.Data.Common;
using DependencyInjection.StaticAccessor;
using Microsoft.Extensions.Logging;

namespace FreeSql
{
    public static class FreeSqlSqliteExtensions
    {
        



        public static void AddSql(this IServiceCollection services, IConfigurationSection section)
        {
            var config = section.Get<DbConfig>() ?? new DbConfig();
            services.Configure<DbConfig>(section);
            IdHelper.SetIdGeneratorOptions(config.WorkerId, (byte)config.WorkerIdBitLength);
            IFreeSql fsql = new FreeSqlBuilder()
                .UseConnectionString(DataType.Sqlite, config.ConnectionString)
                 .UseNameConvert(NameConvertType.PascalCaseToUnderscoreWithLower)//oracle 全部转为大写
                 .UseMonitorCommand(
                    cmd =>
                    {
                        cmd.CommandTimeout = 9999;
                        if (config.WatchCurd)
                        {
                            var p = "";
                            foreach (DbParameter item in cmd.Parameters)
                            {
                                if (p == "") p += "\r\nParameters：\r\n";
                                p += ($"ParameterName:{item.ParameterName},Value:{item.Value}\r\n");
                            }
                            var logger = PinnedScope.ScopedServices?.GetRequiredService<ILogger>();
                            logger?.LogDebug("\r\n*******begin================SQL================**********\r\n" + cmd.CommandText + p + "\r\n*******end================SQL================**********");

                        }
                    })
                .UseNoneCommandParameter(config.NoneCommandParameter)
                // .UseAutoSyncStructure(true) //自动同步实体结构到数据库，只有CRUD时才会生成表
                .Build();

            fsql.UseJsonMap();

            var selectProvider = fsql.Select<object>() as Select0Provider;
            var serverTime = fsql.Select<object>().WithSql($"select {selectProvider._commonUtils.NowUtc} a").First(a => Convert.ToDateTime("a"));
            var timeOffset = DateTime.UtcNow.Subtract(serverTime);

            fsql.Aop.AuditValue += (s, e) =>
            {
                DbHelper.AuditValue(e);
            };

            fsql.Aop.ConfigEntityProperty += (s, e) =>
            {
                DbHelper.ConfigEntityProperty(s, e);
            };
            fsql.GlobalFilter.Apply<IBaseSoftDelete>(nameof(IBaseSoftDelete), a => a.IsDeleted == false);

            //初始化表结构以及种子数据
            DbHelper.ConfigEntity(fsql);

            services.AddSingleton<IFreeSql>(fsql);
            services.AddScoped<UnitOfWorkManager>();
            services.AddScoped(typeof(IRepositoryDefault<>), typeof(RepositoryDefault<>));
            services.AddScoped(typeof(IRepositoryBase<>), typeof(RepositoryBase<>));
            services.AddScoped(typeof(IRepositoryDefault<,>), typeof(RepositoryDefault<,>));
            services.AddScoped(typeof(IRepositoryBase<,>), typeof(RepositoryBase<,>));
            //services.AddFreeRepository(null, ass.ToArray());
            //services.AddScoped(typeof(IBaseRepository<>), typeof(GuidRepository<>));
            //services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>));
            //services.AddScoped(typeof(IBaseRepository<,>), typeof(DefaultRepository<,>));
            //services.AddScoped(typeof(BaseRepository<,>), typeof(DefaultRepository<,>));
        }
    }
}
